package tcp

import (
	"github.com/rs/xid"
	"os"
	"strconv"
	"strings"
	"time"
)

type TcpTag string

func (tt TcpTag) String() string {
	arr := strings.Split(string(tt), ":")
	if len(arr) == 2 && arr[0] == "response" {
		return arr[1]
	}

	return string(tt)
}

func (tt TcpTag) IsResponse() bool {
	arr := strings.Split(string(tt), ":")
	if len(arr) == 2 && arr[0] == "response" {
		return true
	}

	return false
}

type TcpData struct {
	id      string
	tag     TcpTag
	time    string
	podname string
	data    []byte
}

func (tc TcpData) ToBytes() []byte {
	data := []byte(tc.id)
	data = append(data, []byte("\r\n")...)
	data = append(data, []byte(tc.tag)...)
	data = append(data, []byte("\r\n")...)
	data = append(data, []byte(tc.time)...)
	data = append(data, []byte("\r\n")...)
	data = append(data, []byte(tc.podname)...)
	data = append(data, []byte("\r\n")...)
	data = append(data, tc.data...)

	return data
}

func (tc TcpData) String() string {
	str := tc.id + "\r\n" + string(tc.tag) + "\r\n" + tc.time + "\r\n" + tc.podname + "\r\n" + string(tc.data)
	return str
}

func (tc TcpData) Data() []byte {
	return tc.data
}

func (tc TcpData) ID() string {
	return tc.id
}

func (tc TcpData) Tag() TcpTag {
	return tc.tag
}

func (tc TcpData) ResponseData(data []byte) TcpData {
	env := os.Getenv("POD_NAME")
	if env == "" {
		env = "not_known"
	}
	t := TcpData{}
	t.id = tc.id
	t.tag = "response:" + tc.tag
	t.time = strconv.Itoa(int(time.Now().UnixNano()))
	t.podname = env
	t.data = data
	return t
}

func Decode(data []byte) TcpData {
	str := string(data)
	arr := strings.Split(str, "\r\n")
	result := TcpData{}
	result.id = arr[0]
	result.tag = TcpTag(arr[1])
	result.time = arr[2]
	result.podname = arr[3]
	if len(arr) > 4 {
		begin := len("\r\n")*4 + len(arr[0]) + len(arr[1]) + len(arr[2]) + len(arr[3])
		if len(data) > begin {
			result.data = data[begin:]
		}
		return result
	}
	return result
}

func Encode(tag string, data []byte) TcpData {
	id := xid.New().String()
	env := os.Getenv("POD_NAME")
	if env == "" {
		env = "not_known"
	}
	t := strconv.Itoa(int(time.Now().UnixNano()))
	td := TcpData{
		id:      id,
		time:    t,
		tag:     TcpTag(tag),
		podname: env,
		data:    data,
	}

	return td
}
